package com.weimob.mcloud.wechatwork.customer.utils;

import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.metadata.BaseRowModel;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.metadata.Table;
import com.alibaba.excel.support.ExcelTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.springframework.util.CollectionUtils;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;

@Slf4j
public class EasyExcelUtils {


    /**
     * 使用 模型 来读取Excel
     * @param inputStream Excel的输入流
     * @param clazz 模型的类
     * @return 返回 模型 的列表(为object列表,需强转)
     */
    public static List<?> readExcel(InputStream inputStream, ExcelTypeEnum excelTypeEnum, Class<? extends BaseRowModel> clazz, int sheetNumber, int headLineMun) {

        // 解析每行结果在listener中处理
        ModelExcelListener listener = new ModelExcelListener();
        ExcelReader excelReader = new ExcelReader(inputStream, excelTypeEnum, null, listener);
        //默认只有一列表头
        excelReader.read(new Sheet(sheetNumber, headLineMun, clazz));
        return listener.getDatas();
    }

    private static boolean checkParam(Map<String, List<? extends BaseRowModel>> SheetNameAndDateList, ExcelTypeEnum type) {
        if (MapUtils.isEmpty(SheetNameAndDateList)) {
            log.warn("SheetName和excel数据为空");
            return false;
        } else if (type == null) {
            log.warn("导出的excel类型为空");
            return false;
        }
        for (Map.Entry<String, List<? extends BaseRowModel>> dataListEntry : SheetNameAndDateList.entrySet()){
            if(CollectionUtils.isEmpty(dataListEntry.getValue())){
                log.warn("{}数据集为空", dataListEntry.getKey());
                return false;
            }
        }
        return true;
    }

    /**
     * 使用 模型 来读取Excel
     * @param inputStream Excel的输入流
     * @param clazz 模型的类
     * @param excelTypeEnum Excel的格式(XLS或XLSX)
     * @return 返回 模型 的列表(为object列表,需强转)
     */
    public static List<?> readExcelWithModel(InputStream inputStream, Class<? extends BaseRowModel> clazz, ExcelTypeEnum excelTypeEnum, int sheetNumber, int headLineMun) {

        // 解析每行结果在listener中处理
        ModelExcelListener listener = new ModelExcelListener();
        ExcelReader excelReader = new ExcelReader(inputStream, excelTypeEnum, null, listener);
        //默认只有一列表头
        excelReader.read(new Sheet(sheetNumber, headLineMun, clazz));
        return listener.getDatas();
    }

    /**
     * 使用 模型 来写入Excel
     * @param outputStream Excel的输出流
     * @param data 要写入的以 模型 为单位的数据
     * @param table 配置Excel的表的属性
     * @param clazz 模型的类
     * @param excelTypeEnum Excel的格式(XLS或XLSX)
     */
    public static void writeExcelWithModel(OutputStream outputStream, List<? extends BaseRowModel> data, Table table, Class<? extends BaseRowModel> clazz, ExcelTypeEnum excelTypeEnum)  {
        //这里指定需要表头，因为model通常包含表头信息
        ExcelWriter writer = new ExcelWriter(outputStream, excelTypeEnum,true);
        //写第一个sheet, sheet1  数据全是List<String> 无模型映射关系
        Sheet sheet1 = new Sheet(1,0, clazz);
        writer.write(data, sheet1,table);
        writer.finish();
    }

    /**
     * 根据名称获取excel类型
     * @param fileName
     * @return
     */
    public static ExcelTypeEnum getExcelTypeEnum(String fileName) {
        String type = org.apache.commons.lang3.StringUtils.substringAfterLast(fileName, ".");
        ExcelTypeEnum xlsType = ExcelTypeEnum.XLS;
        if (ExcelTypeEnum.XLSX.getValue().equalsIgnoreCase("." + type)) {
            xlsType = ExcelTypeEnum.XLSX;
        }
        return xlsType;
    }

    public static byte[] getSingleSheetExcelBytes(ByteArrayOutputStream outputStream, List<? extends BaseRowModel> dataList, ExcelTypeEnum xlsType, String sheetName) {
        ExcelWriter writer = new ExcelWriter(outputStream, xlsType, true);
        Class<? extends BaseRowModel> aClass = dataList.get(0).getClass();
        Sheet sheet = new Sheet(1,0, aClass);
        sheet.setSheetName(sheetName);
        writer.write(dataList, sheet);
        writer.finish();
        return outputStream.toByteArray();
    }
}
